//引入express
const express = require("express");
//引入路径模块
var path = require("path");
//引入服务js
const app = require("./bin/www");
//引入处理post请求参数的中间件
const bodyParser = require("body-parser");
const multer = require('multer');
const { serveConfig } = require('./config/config')
const { success, fail, } = require("./model/resModel");
var geoip = require('geoip-lite');
const axios = require("axios");
const DBfactory = require("./model/mysql");
var fs = require('fs')
require('express-async-errors');


app.use("/uploads", express.static(path.join(__dirname, "uploads")))
app.get('/', (req, res) => {
    res.sendFile(__dirname + "/pages/" + "index.html") //设置/ 下访问文件位置
});
app.get('/select', (req, res) => {
    res.sendFile(__dirname + "/pages/" + "select.html") //设置/ 下访问文件位置
});
//防止跨域
app.all("*", async (req, res, next) => {
    console.log("有请求,请求接口为:" + serveConfig.agreement + "://" + serveConfig.host + ':' + serveConfig.port + req.url)
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Content-Type", "application/json;charset=utf-8");
    res.header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
    res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
    res.header(
        "Access-Control-Allow-Headers",
        "Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild"
    );

    if (req.method.toLowerCase() == "options") {
        res.sendStatus(200);
        return;
    } else {
        next();
    }
});
//使用bodyParser对post请求参数进行处理
app.use(
    bodyParser.urlencoded({
        extended: false,
    })
);
app.use(bodyParser.json());
let storage = multer.diskStorage({
    //设置上传后文件路径，uploads文件夹会自动创建。
    destination: function (req, file, cb) {
        cb(null, './uploads')
    },
    //给上传文件重命名，获取添加后缀名
    filename: function (req, file, cb) {
        let fileFormat = (file.originalname).split(".");
        let filename = Date.now() + "." + fileFormat[fileFormat.length - 1]
        cb(null, filename);
    }
});
let upload = multer({
    storage: storage
});
// 上传文件
//当请求上传文件
app.post('/upload', upload.single('file'), async (req, res) => {
    //如果文件上传成功，获取文件的名字存入数据库
    if (req.file) {
        let file = req.file;
        //判断文件类型
        let mimetypeList = ["image/jpeg", "image/png", "image/webp", "video/mp4", "video/quicktime"]
        if (!mimetypeList.includes(file.mimetype)) {
            let mimetypeListText = mimetypeList.join(',')
            let url = __dirname + '/uploads/' + file.filename;
            //删除文件
            fs.unlink(url, async (err) => {
                if (err) {
                    console.log('原图删除失败');
                    res.send(fail('原图删除失败'))
                    return;
                }
            })
            return res.send(fail('文件格式错误,只能传输' + mimetypeListText + '格式的文件'))

        }
        //获取ip和地址
        let ip, address;
        ip = req.ip.match(/\d+\.\d+\.\d+\.\d+/) || 0
        if (!ip[0]) {
            address = '未知地点'
        } else {
            // 获取ip
            var geo = geoip.lookup(ip[0]);
            address = await getAddress(geo.ll)
        }
        //文件地址
        let url = '/uploads/' + file.filename
        let fileUrl = serveConfig.agreement + '://' + serveConfig.host + ':' + serveConfig.port + url
        let type = file.mimetype == "image/jpeg" || file.mimetype == "image/png" || file.mimetype == "image/webp" ? 1 : 2
        let sql = "INSERT INTO up_record (address,ip,url,fileUrl,type) VALUES ('" + address + "','" + ip + "','" + url + "','" + fileUrl + "'," + type + ")";

        //执行语句
        await DBfactory.query(sql);
        res.send(success('上传成功', {
            fileUrl,
            url: url,
        }))
    } else {
        res.send(fail('上传失败'))
    }
});
//查询
app.post('/select', async (req, res) => {
    const { page } = req.body
    let sqlCount = "SELECT COUNT(*) as count FROM `up_record`"
    let sqlCountRes = await DBfactory.query(sqlCount);
    let count = sqlCountRes[0].count
    let sql = "SELECT * FROM `up_record` ORDER BY  createtime DESC LIMIT " + (page - 1) * 10 + ",10";
    //执行语句
    let sqlRes = await DBfactory.query(sql);
    for (let i in sqlRes) {
        sqlRes[i].createtime = time(sqlRes[i].createtime);
    }
    // count
    res.send(success('查询成功', { count, list: sqlRes }))
})
//删除
app.post('/del', async (req, res) => {
    const { id } = req.body
    let sql = "SELECT * FROM `up_record` where id = " + id;
    //执行语句
    let sqlRes = await DBfactory.query(sql);
    if (!sqlRes[0]) {
        res.send(fail('查询失败'))
    }
    let url = __dirname + sqlRes[0].url;

    fs.unlink(url, async (err) => {
        if (err) {
            console.log('原图删除失败:', err);
            let errData = JSON.parse(fs.readFileSync(path.join(__dirname, "err", 'err.json'), "utf-8"));
            let time = getNowFormatDate();
            const content = { "type": "delFileErr", "err": err, "time": time }
            errData.push(content)
            fs.writeFile(path.join(__dirname, "err", 'err.json'), JSON.stringify(errData), (err) => {
            })

        }

    })
    let sqlDet = "DELETE FROM up_record WHERE id = " + id;
    //执行语句
    await DBfactory.query(sqlDet);
    console.log('原图删除成功');
    res.send(success('删除成功'))

})
const getNowFormatDate = () => {
    var date = new Date();
    var seperator1 = "-";
    var seperator2 = ":";
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
        + " " + date.getHours() + seperator2 + date.getMinutes()
        + seperator2 + date.getSeconds();
    return currentdate;
}
const time = (time) => {
    var date = new Date(time);
    var result = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
    return result
};

const axiosFun = (url) => {
    return new Promise((resolve, reject) => {
        axios({
            method: "get",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            url

        }).then((response) => {
            // console.log(response.data)
            return resolve(response)

        })
    })

}
const getAddress = async (location) => {
    let lat = location[0];
    let lon = location[1];
    let key = 'bf85908c7cc595f65d608b39a29fcb88'
    let url = 'https://restapi.amap.com/v3/geocode/regeo?output=JSON&location=' + lon + ',' + lat + '&key=' + key + '&radius=1000&extensions=all'
    let response = await axiosFun(url);
    console.log(response.data.addressComponent)
    return response.data.regeocode.addressComponent.province
}